package com.gxa.modules.shiro;

import com.alibaba.fastjson.JSON;
import com.gxa.common.utils.JwtResult;
import com.gxa.common.utils.JwtUtils;
import com.gxa.common.vo.ResultVo;
import com.gxa.modules.jwt.ParseTokenUtils;
import com.gxa.modules.pojo.User;
import org.apache.shiro.web.filter.AccessControlFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

/**
 * @program: microloans_system
 * @description: 测试过滤器
 * @author: LC
 * @create: 2022-01-05 14:51
 */

public class MyTokenFilter extends AccessControlFilter {

    @Autowired(required = false)
    RedisTemplate redisTemplate;


    @Override
    protected boolean isAccessAllowed(ServletRequest servletRequest, ServletResponse servletResponse, Object o) throws Exception {
        /**
         * 判断是否登录，是登录状态就续签jwt，不是登录状态就返回未登录信息
//         */
        System.out.println("--------------isAccessAllowed拦截成功----------------");
        HttpServletRequest request=(HttpServletRequest)servletRequest;

        System.out.println(request.getRequestURI());
        if(
                request.getRequestURI().equals("/user/login")||
                request.getRequestURI().equals("/user/getCaptcha")){
            return true;
        }
        return false;
    }

    private void returnResultJson(ServletResponse servletResponse,int code,String msg) throws IOException {
        ResultVo r=new ResultVo();
        r.setCode(code);
        r.setMsg(msg);
        servletResponse.setCharacterEncoding("utf-8");
        servletResponse.getWriter().write(JSON.toJSONString(r));
        servletResponse.getWriter().flush();
        servletResponse.getWriter().close();
    }


    @Override
    protected boolean onAccessDenied(ServletRequest servletRequest, ServletResponse servletResponse) throws Exception {
        System.out.println("--------------onAccessDenied拦截成功----------------");

        String token=getJwt(servletRequest);//获取token
        System.out.println("前端的token:"+token);
//        User u=ParseTokenUtils.getCurrentUser((HttpServletRequest)servletRequest);
//        System.out.println("=================================="+u);

        if(StringUtils.isEmpty(token)){//token为空表示没登录
            returnResultJson(servletResponse,401,"你还未登录");
            return false;
        }

        //从token中解析出key
        JwtResult result = JwtUtils.validateJwt(token);

        if(result.getClaims()==null){
            returnResultJson(servletResponse,400,"错误的token");
            return false;
        }
        String subjectStr=result.getClaims().getSubject();

        String oldToken=(String)redisTemplate.opsForValue().get(subjectStr);
        System.out.println("redis中找到的token"+oldToken);
        if(oldToken==null){
            //已经过期，提示登录
            returnResultJson(servletResponse,401,"你已退出登录，请重新登录");
            return false;
        }
        if(!oldToken.equals(token)){
            //token不一致，表示登录被挤下线了
            returnResultJson(servletResponse,401,"你的账号已被别人登录");
            return false;
        }
        Long seconds=redisTemplate.opsForValue().getOperations().getExpire(subjectStr);
        System.out.println("token剩余存活时间（秒）:"+seconds);
        //当存活时间小于60s时，续签token
        if(seconds<=60){
            //续签半小时
            redisTemplate.opsForValue().set(subjectStr,oldToken,60*30, TimeUnit.SECONDS);
        }
        return true;
    }

    public String getJwt(ServletRequest servletRequest){
        HttpServletRequest request=(HttpServletRequest)servletRequest;
        String token=request.getHeader("token");
        return token;
    }
}